<template>
  <div>
    <el-form
      :ref="formConf.ref != null ? formConf.ref : formConfBak.ref"
      :model="model"
      :rules="formConf.rules != null ? formConf.rules : formConfBak.rules"
      :label-width="
        formConf.labelWidth != null
          ? formConf.labelWidth
          : formConfBak.labelWidth
      "
      :label-position="
        formConf.labelPosition != null
          ? formConf.labelPosition
          : formConfBak.labelPosition
      "
      :inline="formConf.inline != null ? formConf.inline : formConfBak.inline"
      :label-suffix="
        formConf.labelSuffix != null
          ? formConf.labelSuffix
          : formConfBak.labelSuffix
      "
      :hide-required-asterisk="
        formConf.hideRequiredAsterisk != null
          ? formConf.hideRequiredAsterisk
          : formConfBak.hideRequiredAsterisk
      "
      :show-message="
        formConf.showMessage != null
          ? formConf.showMessage
          : formConfBak.showMessage
      "
      :inline-message="
        formConf.inlineMessage != null
          ? formConf.inlineMessage
          : formConfBak.inlineMessage
      "
      :status-icon="
        formConf.statusIcon != null
          ? formConf.statusIcon
          : formConfBak.statusIcon
      "
      :validate-on-rule-change="
        formConf.validateOnRuleChange != null
          ? formConf.validateOnRuleChange
          : formConfBak.validateOnRuleChange
      "
      :size="formConf.size != null ? formConf.size : formConfBak.size"
      :disabled="
        formConf.disabled != null ? formConf.disabled : formConfBak.disabled
      "
      @validate="formValidate"
    >
      <el-row
        v-for="(elRow, rowIndex) in layout"
        :key="rowIndex"
        :gutter="
          elRow.gutter == null
            ? rowConf.gutter != null
              ? rowConf.gutter
              : rowConfBak.gutter
            : elRow.gutter
        "
        :type="
          elRow.type == null
            ? rowConf.type != null
              ? rowConf.type
              : rowConfBak.type
            : elRow.type
        "
        :justify="
          elRow.justify == null
            ? rowConf.justify != null
              ? rowConf.justify
              : rowConfBak.justify
            : elRow.justify
        "
        :align="
          elRow.align == null
            ? rowConf.align != null
              ? rowConf.align
              : rowConfBak.align
            : elRow.align
        "
        :tag="
          elRow.tag == null
            ? rowConf.tag != null
              ? rowConf.tag
              : rowConfBak.tag
            : elRow.tag
        "
      >
        <el-col
          v-for="(elCol, colIndex) in elRow.elCols"
          :key="colIndex"
          :span="
            elCol.span == null
              ? colConf.span != null
                ? colConf.span
                : colConfBak.span
              : elCol.span
          "
          :offset="
            elCol.offset == null
              ? colConf.offset != null
                ? colConf.offset
                : colConfBak.offset
              : elCol.offset
          "
          :push="
            elCol.push == null
              ? colConf.push != null
                ? colConf.push
                : colConfBak.push
              : elCol.push
          "
          :pull="
            elCol.pull == null
              ? colConf.pull != null
                ? colConf.pull
                : colConfBak.pull
              : elCol.pull
          "
          :xs="
            elCol.xs == null
              ? colConf.xs != null
                ? colConf.xs
                : colConfBak.xs
              : elCol.xs
          "
          :sm="
            elCol.sm == null
              ? colConf.sm != null
                ? colConf.sm
                : colConfBak.sm
              : elCol.sm
          "
          :md="
            elCol.md == null
              ? colConf.md != null
                ? colConf.md
                : colConfBak.md
              : elCol.md
          "
          :lg="
            elCol.lg == null
              ? colConf.lg != null
                ? colConf.lg
                : colConfBak.lg
              : elCol.lg
          "
          :xl="
            elCol.xl == null
              ? colConf.xl != null
                ? colConf.xl
                : colConfBak.xl
              : elCol.xl
          "
          :tag="
            elCol.tag == null
              ? colConf.tag != null
                ? colConf.tag
                : colConfBak.tag
              : elCol.tag
          "
        >
          <el-form-item
            v-if="
              elCol.elFormItem.isShow == null ? true : elCol.elFormItem.isShow
            "
            :ref="elCol.elFormItem.ref"
            :prop="elCol.elFormItem.prop"
            :label="elCol.elFormItem.label"
            :label-width="elCol.elFormItem.labelWidth"
            :required="elCol.elFormItem.required"
            :rules="elCol.elFormItem.rules"
            :error="elCol.elFormItem.error"
            :show-message="elCol.elFormItem.showMessage"
            :inline-message="elCol.elFormItem.inlineMessage"
            :size="elCol.elFormItem.size"
          >
            <template #error="{error}">
              <slot name="error" :error="error"></slot>
            </template>
            <el-input
              v-if="
                elCol.elFormItem.type == 'input' ||
                  elCol.elFormItem.type == 'textarea'
              "
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :placeholder="
                elCol.elFormItem.placeholder != null
                  ? elCol.elFormItem.placeholder
                  : '请输入' + elCol.elFormItem.label
              "
              :disabled="elCol.elFormItem.disabled"
              :maxlength="elCol.elFormItem.maxlength"
              :show-word-limit="elCol.elFormItem.showWordLimit"
              :autosize="elCol.elFormItem.autosize"
              :type="elCol.elFormItem.type"
            />
            <el-select
              v-else-if="elCol.elFormItem.type == 'select'"
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :disabled="elCol.elFormItem.disabled"
              :placeholder="
                elCol.elFormItem.placeholder != null
                  ? elCol.elFormItem.placeholder
                  : '请选择' + elCol.elFormItem.label
              "
            >
              <el-option
                v-for="(option, index) in elCol.elFormItem.options"
                :key="index"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
            <el-radio-group
              v-else-if="elCol.elFormItem.type == 'radio'"
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :disabled="elCol.elFormItem.disabled"
            >
              <el-radio
                v-for="option in elCol.elFormItem.options"
                :key="option.value"
                :label="option.value"
              >
                {{ option.label }}
              </el-radio>
            </el-radio-group>
            <el-date-picker
              v-else-if="
                elCol.elFormItem.type == 'datetime' ||
                  elCol.elFormItem.type == 'datetimerange'
              "
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :disabled="elCol.elFormItem.disabled"
              :picker-options="elCol.elFormItem.pickerOptions"
              :default-time="elCol.elFormItem.defaultTime"
              :placeholder="
                elCol.elFormItem.placeholder != null
                  ? elCol.elFormItem.placeholder
                  : '请选择' + elCol.elFormItem.label
              "
              :format="
                elCol.elFormItem.format == null
                  ? 'yyyy-MM-dd HH:mm:ss'
                  : elCol.elFormItem.format
              "
              :value-format="
                elCol.elFormItem.valueFormat == null
                  ? 'yyyy-MM-dd HH:mm:ss'
                  : elCol.elFormItem.valueFormat
              "
              :type="elCol.elFormItem.type"
              :start-placeholder="
                elCol.elFormItem.startPlaceholder != null
                  ? elCol.elFormItem.startPlaceholder
                  : formConfBak.dateTime.startPlaceholder
              "
              :end-placeholder="
                elCol.elFormItem.endPlaceholder != null
                  ? elCol.elFormItem.endPlaceholder
                  : formConfBak.dateTime.endPlaceholder
              "
              :range-separator="
                elCol.elFormItem.rangeSeparator != null
                  ? elCol.elFormItem.rangeSeparator
                  : formConfBak.dateTime.rangeSeparator
              "
              align="right"
            />
            <el-cascader
              v-else-if="elCol.elFormItem.type == 'cascader'"
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :placeholder="
                elCol.elFormItem.placeholder != null
                  ? elCol.elFormItem.placeholder
                  : '请选择' + elCol.elFormItem.label
              "
              :disabled="elCol.elFormItem.disabled"
              :options="elCol.elFormItem.options"
              :props="elCol.elFormItem.props"
            />
            <el-autocomplete
              v-else-if="elCol.elFormItem.type == 'autocomplete'"
              v-model="model[elCol.elFormItem.prop]"
              :style="elCol.elFormItem.style"
              :placeholder="
                elCol.elFormItem.placeholder != null
                  ? elCol.elFormItem.placeholder
                  : '请输入' + elCol.elFormItem.label
              "
              :disabled="elCol.elFormItem.disabled"
              :maxlength="elCol.elFormItem.maxlength"
              :show-word-limit="elCol.elFormItem.showWordLimit"
              :autosize="elCol.elFormItem.autosize"
              :fetch-suggestions="querySearch"
              :trigger-on-focus="elCol.elFormItem.triggerOnFocus"
              :value-key="
                elCol.elFormItem.valueKey
                  ? elCol.elFormItem.valueKey
                  : formConf.autocompleteValueKey
                  ? formConf.autocompleteValueKey
                  : formConfBak.autocompleteValueKey
              "
              @select="select"
              @focus="focus(elCol)"
            ></el-autocomplete>
            <slot v-else :name="elCol.elFormItem.type" :elCol="elCol"></slot>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-row
      v-if="btnConf.show != null ? btnConf.show : btnConfBak.show"
      :type="btnConf.type != null ? btnConf.type : btnConfBak.type"
      :gutter="btnConf.gutter != null ? btnConf.gutter : btnConfBak.gutter"
      :justify="btnConf.justify != null ? btnConf.justify : btnConfBak.justify"
      :align="btnConf.align != null ? btnConf.align : btnConfBak.align"
      :tag="btnConf.tag != null ? btnConf.tag : btnConfBak.tag"
      :style="btnConf.style"
      class="myFormRow"
    >
      <el-button
        v-for="(btnItem, btnIndex) in btnConf.buttons != null
          ? btnConf.buttons
          : btnConfBak.buttons"
        v-show="btnItem.show != null ? btnItem.show : btnConfBak.show"
        :key="btnIndex"
        :type="btnItem.type"
        :size="btnItem.size != null ? btnItem.size : btnConfBak.size"
        :plain="btnItem.plain != null ? btnItem.plain : btnConfBak.plain"
        :round="btnItem.round != null ? btnItem.round : btnConfBak.round"
        :circle="btnItem.circle != null ? btnItem.circle : btnConfBak.circle"
        :loading="btnItem.loading"
        :disabled="btnItem.disabled"
        :icon="btnItem.icon != null ? btnItem.icon : btnConfBak.icon"
        :autofocus="
          btnItem.autofocus != null ? btnItem.autofocus : btnConfBak.autofocus
        "
        :native-type="
          btnItem.nativeType != null
            ? btnItem.nativeType
            : btnConfBak.nativeType
        "
        :style="btnItem.style"
        @click="btnClick(btnItem)"
      >
        {{ btnItem.name }}
      </el-button>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'MyForm',
  components: {},
  props: {
    model: {
      type: Object,
      required: true
    },
    layout: {
      type: Array,
      required: true
    },
    formConf: {
      type: Object,
      default() {
        return {}
      }
    },
    btnConf: {
      type: Object,
      default() {
        return {}
      }
    },
    rowConf: {
      type: Object,
      default() {
        return {}
      }
    },
    colConf: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      formConfBak: {
        ref: 'form',
        size: 'small',
        labelWidth: '120px',
        labelSuffix: '：',
        dateTime: {
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
          rangeSeparator: '至'
        },
        autocompleteValueKey: 'label'
      },
      btnConfBak: {
        gutter: 0,
        type: 'flex',
        justify: 'center',
        align: 'middle',
        plain: false,
        round: false,
        circle: false,
        disabled: false,
        autofocus: false,
        nativeType: 'button',
        show: true,
        size: 'small',
        buttons: [
          { name: '提交', type: 'primary' },
          { name: '重置', callback: false }
        ]
      },
      rowConfBak: {
        gutter: null
      },
      colConfBak: {
        offset: null
      },
      activeElCol: null
    }
  },
  watch: {},
  created() {
    const buttons =
      this.btnConf.buttons != null
        ? this.btnConf.buttons
        : this.btnConfBak.buttons
    for (let i = 0; i < buttons.length; i++) {
      this.$set(buttons[i], 'loading', false)
    }
  },
  methods: {
    formValidate(...args) {
      this.$emit('validate', ...args)
    },
    select(...args) {
      this.$emit('select', ...args, this.activeElCol)
    },
    focus(elCol) {
      this.activeElCol = elCol
    },
    querySearch(queryString, cb) {
      if (this.activeElCol.elFormItem.options == null) {
        this.activeElCol.elFormItem.options = []
      }
      const results = queryString
        ? this.activeElCol.elFormItem.options.filter(
            this.createFilter(queryString)
          )
        : this.activeElCol.elFormItem.options
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createFilter(queryString) {
      return (restaurant) => {
        return (
          restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
          0
        )
      }
    },
    btnClick(btnItem) {
      if (
        btnItem.name === '重置' &&
        btnItem.callback !== undefined &&
        btnItem.callback === false
      ) {
        this.resetFields()
      } else {
        this.$emit('btnClick', btnItem)
      }
    },
    resetFields() {
      const ref =
        this.formConf.ref != null ? this.formConf.ref : this.formConfBak.ref
      console.log('ref:' + ref)
      this.$refs[ref].resetFields()
    }
  }
}
</script>

<style scoped>
.myFormRow {
  margin-top: 20px;
}
</style>
